#include "asr_server.h"

#include "log.h"

namespace chat {
// ASRServerImpl

ASRServerImpl::ASRServerImpl(BaiDuYunASRClientPtr client) : client_(client) {}

void ASRServerImpl::SpeechRecognition(
    ::google::protobuf::RpcController* controller,
    const ::chat::SpeechRecognitionReq* request,
    ::chat::SpeechRecognitionRsp* response, ::google::protobuf::Closure* done) {
    brpc::ClosureGuard closure_guard(done);

    // 1. 从请求中拿到pcm数据
    std::string pcm_data = request->speech_content();

    // 2. 进行语音识别
    std::string err_message;
    std::string ret = client_->asr(pcm_data, &err_message);

    // 3. 根据识别结果构建响应
    response->set_request_id(request->request_id());
    response->set_errmsg(err_message);
    if (ret == "") {
        LOG_ERROR("语音识别失败: {}", err_message);

        response->set_success(false);
    } else {
        response->set_success(true);
        response->set_recognition_result(ret);
    }
}

// -------------------------------------------------------------------

// ASRServer

void ASRServer::start() { brpc_server_->RunUntilAskedToQuit(); }

// -------------------------------------------------------------------

// ASRServerBuilder

void ASRServerBuilder::makeAsrClient(const std::string& app_id,
                                     const std::string& app_key,
                                     const std::string& secret_key) {
    asr_client_ =
        std::make_shared<BaiDuYunASRClient>(app_id, app_key, secret_key);
}

void ASRServerBuilder::makeRegisterClient(const std::string& register_name,
                                          const std::string& etcd_host,
                                          const std::string& access_host) {
    register_client_ = std::make_shared<Registry>(etcd_host);

    register_client_->registry(register_name, access_host);
}

void ASRServerBuilder::makeBrpcServer(const uint16_t prot,
                                      const int idle_timeout_sec,
                                      const int num_threads) {
    if (asr_client_ == nullptr) {
        LOG_FATAL("语音识别客户端未实例化");
        abort();
    }
    
    brpc_server_ = std::make_shared<brpc::Server>();

    // 2. 向服务器中，新增SpeechService服务
    ASRServerImpl* speech_service = new ASRServerImpl(asr_client_);
    if (-1 == brpc_server_->AddService(
                  speech_service,
                  brpc::ServiceOwnership::SERVER_OWNS_SERVICE)) {
        LOG_ERROR("RPC添加服务失败");
        abort();
    }

    // 3. 启动服务器
    brpc::ServerOptions options;
    options.idle_timeout_sec = idle_timeout_sec;
    options.num_threads = num_threads;

    if (-1 == brpc_server_->Start(prot, &options)) {
        LOG_ERROR("RPC服务启动失败");
        abort();
    }
}

ASRServerPtr ASRServerBuilder::build() {
    if (asr_client_ == nullptr) {
        LOG_FATAL("语音识别客户端未实例化");
        abort();
    }
    if (register_client_ == nullptr) {
        LOG_FATAL("服务注册客户端未实例化");
        abort();
    }
    if (brpc_server_ == nullptr) {
        LOG_FATAL("RPC服务未实例化");
        abort();
    }

    return std::make_shared<ASRServer>(asr_client_, register_client_,
                                       brpc_server_);
}
}  // namespace chat